在昨天有聊到說可以透過繼承來讓子類延續父類的內容繼續延伸,我們不見得需要在父類時實作內部函式,可以先給個型別讓其子類來實作他,這種可以同時實現多種實作的方式稱為多型
abstract class Shape {
abstract getArea(): number;
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
getArea(): number {
return Math.PI * this.radius ** 2;
}
}
class Rectangle extends Shape {
constructor(private width: number, private height: number) {
super();
}
getArea(): number {
return this.width * this.height;
}
}
function printArea(shape: Shape) {
console.log(`The area is: ${shape.getArea()}`);
}
const circle = new Circle(5);
const rectangle = new Rectangle(4, 6);
printArea(circle); // The area is: 78.53981633974483
printArea(rectangle); // The area is: 24
除了類對類的繼承外,我們也可以透過 interface 的實作來實現多型
interface Printable {
print(): void;
}
class Book implements Printable {
print() {
console.log("Printing a book");
}
}
class Document implements Printable {
print() {
console.log("Printing a document");
}
}
function printItem(item: Printable) {
item.print();
}
printItem(new Book()); // Printing a book
printItem(new Document()); // Printing a document
又或者是透過泛型來實現
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("myString"); // type of output1 is 'string'
let output2 = identity<number>(100); // type of output2 is 'number'
以下為一個實際上的範例
interface State {
name: string;
}
interface Action {
type: string;
}
class BaseState implements State {
constructor(public name: string) {}
}
class UserState extends BaseState {
constructor(public userId: number) {
super("UserState");
}
}
class ProductState extends BaseState {
constructor(public productId: number) {
super("ProductState");
}
}
function reducer(state: State, action: Action): State {
switch (action.type) {
case "UPDATE_USER":
return new UserState(1);
case "UPDATE_PRODUCT":
return new ProductState(100);
default:
return state;
}
}
// 使用示例
let state: State = new BaseState("Initial");
console.log(state); // { name: "Initial" }
state = reducer(state, { type: "UPDATE_USER" });
console.log(state); // { name: "UserState", userId: 1 }
state = reducer(state, { type: "UPDATE_PRODUCT" });
console.log(state); // { name: "ProductState", productId: 100 }
當熟悉多型、泛型和繼承後將可以降低許多重複代碼的使用,讓代碼更加乾淨且明確